
#include "mainwindow.h"
#include "dialog.h"
#include "ui_mainwindow.h"

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    setWindowTitle("扫坤");

    QMenu* menu_newGame=new QMenu("新游戏",this);
    QMenu* menu_Difficulty=new QMenu("难度",this);
    ui->menubar->addMenu(menu_newGame);
    ui->menubar->addMenu(menu_Difficulty);
    connect(menu_newGame,SIGNAL(aboutToShow()),this,SLOT(slot_newGame()));

    QAction* Easy=new QAction("简单",this);
    QAction* Middle=new QAction("中等",this);
    QAction* Difficult=new QAction("困难",this);
    QAction* Self=new QAction("自定义",this);

    menu_Difficulty->addAction(Easy);
    menu_Difficulty->addAction(Middle);
    menu_Difficulty->addAction(Difficult);
    menu_Difficulty->addAction(Self);

    connect(Easy,SIGNAL(triggered()),this,SLOT(slot_level_Easy()));
    connect(Middle,SIGNAL(triggered()),this,SLOT(slot_level_Middle()));
    connect(Difficult,SIGNAL(triggered()),this,SLOT(slot_level_Difficult()));
    connect(Self,SIGNAL(triggered()),this,SLOT(slot_level_Self()));

    dialogSelf=new Dialog(this);
    connect(dialogSelf,SIGNAL(dia_test()),this,SLOT(slot_level_Self_get()));

    flagImage=QPixmap("E:/C++/qt/picture/flag.bmp");
    kunImage=QPixmap("E:/C++/qt/picture/Kun3.jpg");

    rows=9;
    cols=9;
    kun=10;

    newGame();
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::overGame()
{
    m_bGameFail=true;
    for(int i=0;i<items.size();i++)
    {
        for(int j=0;j<items[i].size();j++)
        {
            if(items[i][j]->isKun)
            {
                items[i][j]->isMarked=true;
            }
            else
            {
                items[i][j]->isMarked=false;
                items[i][j]->isOpen=true;
            }
        }
    }
}
void MainWindow::initItems()
{
    Kuns.clear();
    //对坤进行随机初始化
    for(int i=0;i<kun;i++)
    {
        srand(QTime::currentTime().msec());
        int x=rand()%cols;
        int y=rand()%rows;

        while(Kuns.contains(QPoint(x,y)))//已经包含这个坤，再随机生成一个坐标
        {
            x=rand()%cols;
            y=rand()%rows;
        }
        Kuns.append(QPoint(x,y));
    }
    for(int i=0;i<cols;i++)
    {
        QVector<Item*>rowItems;//创建Item对象指针容器
        for(int j=0;j<rows;j++)
        {
            QPoint pos=QPoint(i,j);
            Item* pItem=new Item(pos);
            if(Kuns.contains(pos))//该位置为坤
            {
                pItem->isKun=true;
            }
            rowItems.append(pItem);
        }
        items.append(rowItems);
    }
    //计算元素数字
    for(int i=0;i<cols;i++)
    {
        for(int j=0;i<rows;j++)
        {
            if(items[i][j]->isKun)
            {
                continue;
            }
            int nCountKun=0;
            for(int m=-1;m<=1;m++)
            {
                for(int n=-1;n<=1;n++)
                {
                    if(m==0&&n==0)
                    {
                        continue;
                    }
                    QPoint ptNew=QPoint(i+m,j+n);
                    if(!pointInGameArea(ptNew))
                    {
                        continue;
                    }
                    if(items[i+m][j+n]->isKun)
                    {
                        nCountKun++;
                    }
                }
            }
            items[i][j]->number=nCountKun;
        }
    }
}
void MainWindow::releaseItems()
{
    for(int i=0;i<items.size();i++)
    {
        for(int j=0;j<items[i].size();j++)
        {
            if(items[i][j]!=nullptr)
            {
                delete items[i][j];
                items[i][j]=nullptr;
            }
        }
    }
    items.clear();
}
void MainWindow::newGame()
{
    m_bGameFail=false;
    resize(START_X*2+cols*RECT_WIDTH,START_Y*2+rows*RECT_HEIGHT);

    releaseItems();
    initItems();
}
void MainWindow::paintEvent(QPaintEvent *)
{
    drawBoard();
    drawItems();

    update();
}
void MainWindow::mousePressEvent(QMouseEvent *event)
{
    QPoint pt;
    pt.setX((event->pos().x()-START_X)/RECT_WIDTH);
    pt.setY((event->pos().y()-START_Y)/RECT_HEIGHT);

    if(!pointInGameArea(pt))
    {
        return;
    }
    Item*pItem=items[pt.x()][pt.y()];
    if(event->button()==Qt::LeftButton)
    {
        if(!pItem->isMarked&&!pItem->isOpen)
        {
            if(pItem->isKun)
            {
                overGame();
                QMessageBox::StandardButton ret;
                ret=QMessageBox::information(nullptr,"游戏结束","再试一次？",QMessageBox::Yes,QMessageBox::No);
                if(ret==QMessageBox::Yes)
                {
                    newGame();
                }
                else
                {
                    QApplication::quit();
                }
                return;
            }
            else
            {
                pItem->isOpen=true;
                if(pItem->number==0)
                {
                    openEmptyItem(pt);
                }
                if(findAll())
                {
                    QMessageBox::StandardButton ret;
                    ret=QMessageBox::information(nullptr,"游戏结束","通关！再试一次？",QMessageBox::Yes,QMessageBox::No);
                    if(ret==QMessageBox::Yes)
                    {
                        newGame();
                    }
                    else
                    {
                        QApplication::quit();
                    }
                    return;
                }
            }
        }
    }
    else if(event->button()==Qt::RightButton)
    {
        if (pItem->isMarked) //已标记过的，取消标记
        {
            pItem->isMarked = false;
        }
        else if (!pItem->isOpen)
        {
           pItem->isMarked = true;
        }
    }
}
void MainWindow::openEmptyItem(QPoint pt)
{
    QVector<QPoint> directions;
    directions.push_back(QPoint(-1,0));
    directions.push_back(QPoint(1,0));
    directions.push_back(QPoint(0,-1));
    directions.push_back(QPoint(0,1));
    for(int i=0;i<directions.size();i++)
    {
        QPoint ptNew=pt+directions[i];
        if(!pointInGameArea(ptNew))
        {
            continue;
        }
        Item*pItem=items[ptNew.x()][ptNew.y()];
        if(!pItem->isKun&&!pItem->isMarked&&!pItem->isOpen&&!(pItem->number==0))
        {
            pItem->isOpen=true;
            QVector<QPoint> directions2= directions;
            directions2.push_back(QPoint(-1,1));
            directions2.push_back(QPoint(1,1));
            directions2.push_back(QPoint(1,-1));
            directions2.push_back(QPoint(1,1));
            for(int j=0;j<directions2.size();j++)
            {
                QPoint ptNew2=ptNew+directions2[j];
                if(!pointInGameArea(ptNew2))
                {
                    continue;
                }
                Item*pItem2=items[ptNew2.x()][ptNew2.y()];
                if(!pItem2->isKun&&!pItem2->isMarked&&!pItem2->isOpen&&!(pItem2->number>0))
                {
                    pItem2->isOpen=true;
                }
            }
            openEmptyItem(ptNew);
        }
    }

}
void MainWindow::drawBoard()
{
    QPainter painter(this);
    painter.setBrush(Qt::lightGray);
    painter.drawRect(0,0,width(),height());
}
void MainWindow::drawItems()
{
    QPainter painter(this);
    painter.setBrush(Qt::lightGray);
    painter.setPen(QPen(QColor(Qt::black),2));
    for(int i=0;i<cols;i++)
    {
        for(int j=0;j<rows;j++)
        {
            drawItem(painter,items[i][j]);
        }
    }
}
void MainWindow::drawItem(QPainter &painter, Item *pItem)
{
    if(pItem->isMarked)
    {
        if(m_bGameFail)//游戏结束
        {
            QRect rcSrc(0,0,flagImage.width(),flagImage.height());
            QRect rcTarget(START_X+pItem->m_pos.x()*RECT_WIDTH+2,START_Y+pItem->m_pos.y()*RECT_HEIGHT+2,RECT_WIDTH-4,RECT_HEIGHT-4);
            painter.drawPixmap(rcTarget,kunImage,rcSrc);
        }
        else//游戏未结束
        {
            QRect rcSrc(0,0,flagImage.width(),flagImage.height());
            QRect rcTarget(START_X+pItem->m_pos.x()*RECT_WIDTH+2,START_Y+pItem->m_pos.y()*RECT_HEIGHT+2,RECT_WIDTH-4,RECT_HEIGHT-4);
            painter.drawPixmap(rcTarget,flagImage,rcSrc);
        }
        painter.setBrush(Qt::transparent);//设置为透明
        painter.drawRect(START_X+pItem->m_pos.x()*RECT_WIDTH+2,START_Y+pItem->m_pos.y()*RECT_HEIGHT+2,RECT_WIDTH-4,RECT_HEIGHT-4);
        return;
    }
    else if(pItem->isOpen)
    {
        if(pItem->number==0)//数字为0
        {
            painter.setBrush(Qt::white);
        }
        else//数字不为0
        {
            QFont font;
            font.setPointSize(20);
            font.setFamily("msyh");

            painter.setBrush(Qt::white);
            painter.drawRect(START_X+pItem->m_pos.x()*RECT_WIDTH,START_Y+pItem->m_pos.y()*RECT_HEIGHT,RECT_WIDTH,RECT_HEIGHT);

            painter.setBrush(Qt::black);
            painter.setFont(font);
            painter.drawText(START_X+pItem->m_pos.x()*RECT_WIDTH+8,START_Y+pItem->m_pos.y()*RECT_HEIGHT+20,QString("%1").arg(pItem->number));
            return;
        }
    }
    else
    {
        painter.setBrush(Qt::blue);
    }
    painter.drawRect(START_X+pItem->m_pos.x()*RECT_WIDTH,START_Y+pItem->m_pos.y()*RECT_HEIGHT,RECT_WIDTH,RECT_HEIGHT);
}
bool MainWindow::findAll()
{
    bool bFindAll=true;
    for(int i=0;i<items.size();i++)
    {
        for(int j=0;j<items[i].size();j++)
        {
            Item* pItem = items[i][j];
            if(pItem->isKun)
            {
                if(!pItem->isOpen)
                {
                    bFindAll=false;
                }
            }
        }
    }
    return bFindAll;
}
bool MainWindow::pointInGameArea(QPoint pt)
{
    if(pt.x()>=0 && pt.x()< cols && pt.y()>=0 && pt.y()< rows)
    {
        return true;
    }
    return false;
}
void MainWindow::slot_newGame()
{
    newGame();
}
void MainWindow::slot_level_Easy()
{
    rows=9;
    cols=9;
    kun=10;
    newGame();
}
void MainWindow::slot_level_Middle()
{
    rows=16;
    cols=16;
    kun=40;
    newGame();
}
void MainWindow::slot_level_Difficult()
{
    rows=16;
    cols=30;
    kun=99;
    newGame();
}
void MainWindow::slot_level_Self()
{
    dialogSelf->show();
}
void MainWindow::slot_level_Self_get()
{
    rows=dialogSelf->getRows();
    cols=dialogSelf->getCols();
    kun=dialogSelf->getKun();
    qDebug()<<rows;
    qDebug()<<cols;
    qDebug()<<kun;

    newGame();
}
